#import <UIKit/UIKit.h>
#import <CoreGraphics/CGGeometry.h>
#import <Foundation/Foundation.h>
#import "UIFilePickerController.h"

@implementation UIFilePickerController
static UIFilePickerController	*sharedPicker = nil;
- (id) init
{
	if ((self = [super init]))
	{
		sharedPicker = self;
		fileManager = [NSFileManager defaultManager];
		files = [NSMutableArray new];
		selectedFiles = [NSMutableArray new];
		if(fileTypes == nil) fileTypes = [NSMutableArray new];
	}
	return self;
}

+ (UIFilePickerController *) sharedPicker
{
	return sharedPicker ? sharedPicker : [[self alloc] init];
}

- (id) delegate
{
	return delegate;
}

- (void) setDelegate:(id)newDelegate
{
	delegate = newDelegate;
}

- (NSArray *) fileTypes
{
	return fileTypes;
}

- (void) setFileTypes:(NSArray *)newTypes
{
	if(fileTypes != newTypes)
	{
		[fileTypes release];
		fileTypes = [newTypes retain];
	}
}

- (NSString *) path
{
	return [fileManager currentDirectoryPath];
}

- (void) setPath:(NSString *)newPath
{
	[fileManager changeCurrentDirectoryPath:newPath];
}

- (void) viewWillAppear:(BOOL)animated
{
	[self scanFiles];
}

- (void) loadView		// UIFilePickerView
{	
	if([self path] == nil) [self setPath:NSHomeDirectory()];
	if([self title] == nil)	[self setTitle:@"Choose a file"];

	pickerView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
	
	navBar = [[UINavigationBar alloc] init];
	[navBar setFrame:CGRectMake(0.0, 0.0, 320, 44)];
	
	UINavigationItem *pickerTitle = [[UINavigationItem alloc] initWithTitle:[self title]];
	
	UIBarButtonItem *cancelButton =	[[UIBarButtonItem alloc] 
						initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
						target:self 
						action:@selector(cancelAction)
					];
	[pickerTitle setLeftBarButtonItem:cancelButton];

	UIBarButtonItem *homeButton = 	[[UIBarButtonItem alloc] 
						initWithTitle:@"Home"
						style:UIBarButtonItemStylePlain
						target:self 
						action:@selector(changePathToHome)
					];
	[pickerTitle setRightBarButtonItem:homeButton];

	[navBar pushNavigationItem:pickerTitle animated:YES];

	[pickerView addSubview:navBar];
	[cancelButton release];
	[homeButton release];
	[pickerTitle release];

	filesTable = [[UITableView alloc] initWithFrame:CGRectMake(0.0, 44, 320, 416) style:UITableViewStylePlain];
	[filesTable setDataSource:self];
	[filesTable setDelegate:self];
	[filesTable setRowHeight:32.0];

	[pickerView addSubview:filesTable];
	[self setView:pickerView];
}

- (void) cancelAction
{
	if ([delegate respondsToSelector:@selector(filePickerCancelled:)])
	{ 
		[delegate performSelector:@selector(filePickerCancelled:) withObject:self];
	}
	else
	{
		[[self parentViewController] 
			performSelector:@selector(dismissModalViewControllerAnimated:) 
			withObject:[NSNumber numberWithBool:YES]
		];
	}
	[selectedFiles removeAllObjects];
}

- (void) openAction
{
	if ([delegate respondsToSelector:@selector(filePicker:finishedWithFiles:)])
	{ 
		[delegate performSelector:@selector(filePicker:finishedWithFiles:) withObject:self withObject:selectedFiles];
	}
	else
	{
		[[self parentViewController] 
			performSelector:@selector(dismissModalViewControllerAnimated:) 
			withObject:[NSNumber numberWithBool:YES]
		];
	}
	[selectedFiles removeAllObjects];
}

- (void) changePathToHome
{
	[self setPath:NSHomeDirectory()];
	[self scanFiles];
}

- (void) scanFiles
{
	BOOL isDir;
	NSMutableArray *dirSorter = [NSMutableArray new];
	NSMutableArray *fileSorter = [NSMutableArray new];

	[files removeAllObjects];
	
	if(![[self path] isEqualToString:@"/"]) [files addObject:@"../"];

	NSDirectoryEnumerator *dirEnum = [fileManager enumeratorAtPath:[fileManager currentDirectoryPath]];
	for (NSString *entry in dirEnum)
	{
		if( ([[[dirEnum fileAttributes] fileType] isEqualToString:NSFileTypeDirectory]) || (([[[dirEnum fileAttributes] fileType] isEqualToString:NSFileTypeSymbolicLink]) && (([fileManager fileExistsAtPath:[[fileManager currentDirectoryPath] stringByAppendingString:entry] isDirectory:&isDir] && isDir))) )
		{
			[dirSorter addObject:[entry stringByAppendingString:@"/"]];
			[dirEnum skipDescendents];
		}
		else
		{
 			if([fileTypes containsObject:[entry pathExtension]] || ([fileTypes count] == 0))
			{
				[fileSorter addObject:entry];
 			}
		}
	}
	[dirSorter sortUsingSelector:@selector(caseInsensitiveCompare:)];
	[files addObjectsFromArray:dirSorter];
	[dirSorter release];
	dirCount = [files count];

	[fileSorter sortUsingSelector:@selector(caseInsensitiveCompare:)];
	[files addObjectsFromArray:fileSorter];
	[fileSorter release];

	[filesTable reloadData];
}

- (NSInteger) numberOfSectionsInTableView:(UITableView *)table
{
	return 1;	
}

- (NSInteger) tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
{
	return [files count];
}

- (NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
	if([[self path] length] > 30)		// rough truncation
	{
		return [@"..." stringByAppendingString:[[self path] substringFromIndex:([[self path] length] - 30)]];
	}
	else
	{
		return [self path];
	}
}

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
	NSString *file = (NSString *)[[files objectAtIndex:[indexPath row]] copy];
	UITableViewCell *cell = [filesTable dequeueReusableCellWithIdentifier:@"any-cell"];
	cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"any-cell"] autorelease];
	[cell setText:file];
	if([indexPath row] < dirCount)			// is Folder
	{
		[cell setFont:[UIFont boldSystemFontOfSize:[UIFont labelFontSize]]];
		[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
		[[cell backgroundView] setBackgroundColor:[UIColor lightGrayColor]];
		if([file isEqualToString:@"../"]) [cell setText:@". . / [Parent Folder]"];
	}
	else						// is File
	{
		[cell setTextColor:[UIColor darkGrayColor]];
		[cell setFont:[UIFont boldSystemFontOfSize:[UIFont systemFontSize]]];
	}
	[file release];
	return cell;
}

- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
	NSString *file = (NSString *)[[files objectAtIndex:[indexPath row]] copy];
	if([indexPath row] < dirCount)			// is Folder
	{
		[self setPath:file];
		[self scanFiles];
	}
	else						// is File
	{
		[selectedFiles addObject:[[fileManager currentDirectoryPath] stringByAppendingPathComponent:file]];
		[self openAction];
	}
	[file release];
	[tableView deselectRowAtIndexPath:indexPath animated:YES];
}

- (void) dealloc
{
	[fileManager release];
	[fileTypes release];
	[filesTable release];
	[selectedFiles release];
	[files release];
	[navBar release];
	[pickerView release];
	[delegate release];

	[super dealloc];
}

@end	//endimp	UIFilePickerController